package com.mk.service.platform;


import act.apidoc.Description;
import act.controller.Controller;
import act.validation.NotBlank;
import com.mk.domain.CpResource;
import com.mk.domain.CpUser;
import com.mk.enums.ErrorCode;
import com.mk.exception.UserException;
import com.mk.interceptor.ITranslate;
import com.mk.util.S2;
import org.osgl.mvc.annotation.*;
import org.osgl.util.S;

import javax.inject.Inject;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@SuppressWarnings("unused")
@Controller("cpResource")
public class CpResourceService extends BasePlatformService {
    @Inject
    private CpResource.Mapper cpResourceMapper;

    //获取用户权限菜单等
    private List<CpResource> userCusResource(CpUser user) {
        //region 读取菜单
        List<CpResource> resourceList = cpResourceMapper.backGetResByUserid(user.getUserid());
        //无权访问
        UserException.throwIf(resourceList.isEmpty(), ErrorCode.E201004);

        //region解析菜单
        List<CpResource> res = new ArrayList<>();
        List<String> ids = new ArrayList<>();

        resourceList.forEach(a -> {
            if (a.getResourcepid() != null) {
                List<CpResource> tempList = resourceList
                    .stream()
                    .filter(d -> S.eq(d.getId(), a.getResourcepid()))
                    .collect(Collectors.toList());
                if (!tempList.isEmpty()) {
                    CpResource temp = tempList.get(0);
                    if (temp.getMenus() == null) temp.setMenus(new ArrayList<>());
                    temp.getMenus().add(a);
                    ids.add(a.getId());
                }
            }
        });
        resourceList.forEach(a -> {
            if (ids.stream().noneMatch(b -> b.equals(a.getId()))) {
                a.setLevel(1);
                if (a.getMenus() != null) {
                    a.getMenus().forEach(b -> {
                        if (S.isNotBlank(b.getResourceurl())) {
                            if (S.isBlank(a.getResourceurl())) a.setResourceurl(b.getResourceurl());
                        }
                        if (b.getMenus() != null && !b.getMenus().isEmpty()) {
                            a.setLevel(2);
                            b.getMenus().forEach(c -> {
                                if (S.isNotBlank(c.getResourceurl())) {
                                    if (S.isBlank(a.getResourceurl())) a.setResourceurl(c.getResourceurl());
                                    if (S.isBlank(b.getResourceurl())) b.setResourceurl(c.getResourceurl());
                                }
                            });
                        }
                    });
                }
                res.add(a);
            }
        });
        //endregion
        return res;
    }


    @Description("获取当前登录人资源列表")
    @With(ILogin.class)
    @GetAction("getRes.json")
    public List<CpResource> getMyRes() {
        return userCusResource(me);
    }


    @Description("获取按钮权限们")
    @With(ILogin.class)
    @GetAction("getPermissions.json")
    public List<String> getPermissions() {
        return cpResourceMapper.getPermissions(me.getUserid());
    }

    /**
     * 递归的将所有子类都赋予父类的属性
     */
    private void findSon(CpResource dto, List<CpResource> list) {
        List<CpResource> sublist = list.stream().filter(
            d -> S.eq(d.getResourcepid(), (dto.getResourceid()))
        ).collect(Collectors.toList());
        if (!sublist.isEmpty()) {
            sublist.forEach(subdto -> findSon(subdto, list));
            dto.setMenus(sublist);
        }
    }

    @GetAction("list.json")
    @With(ILogin.class)
    @Description("通用-资源列表请求-资源树(已实现)")
    public List<CpResource> listRes(
        @Description("角色id")
            String roleid
    ) {
        CpResource cpResource = new CpResource();
        List<CpResource> list = cpResourceMapper.template(cpResource);
        list.sort(Comparator.comparing(CpResource::getOrderno));
        List<CpResource> result = new ArrayList<>();
        list.forEach(dto -> {
            findSon(dto, list);
            if (S.isBlank(dto.getResourcepid())) {
                result.add(dto);
            }
        });
        return result;
    }

    @GetAction("ssoroleResourceTree.json")
    @With(ILogin.class)
    @Description("通用-角色-角色资源树，返回该角色拥有的资源树列表(已实现)")
    public List<CpResource> ssoroleResource(
        @Description("角色主键")
        @NotBlank String roleid
    ) {
        List<CpResource> result = new ArrayList<>();
        List<CpResource> list = cpResourceMapper.backGetResByRoleid(roleid);
        if (list != null && list.size() > 0) {
            list.forEach(dto -> {
                findSon(dto, list);
                if (dto.getMenus() == null || dto.getMenus().size() == 0) {
                    result.add(dto);
                }
            });
        }
        return result;
    }



    @PostAction("add.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-新增资源，返回新增资源的主键(已实现)")
    public String addRes(
        @Description("要增加的资源对象")
        @NotNull(message = "必须传递资源数据") @Valid CpResource cpResource
    ) {
        UserException.throwIf(S.isBlank(cpResource.getResourcecode()), ErrorCode.E200000);
        String sameCodeName = cpResourceMapper.comCheckResourceCode(cpResource.getResourcecode(), null);
        UserException.throwIf(S.isNotBlank(sameCodeName), S.fmt("编码%s已经被菜单:%s使用!", cpResource.getResourcecode(), sameCodeName));
        cpResource.setResourceid(S2.UUID());
        cpResourceMapper.insert(cpResource);
        return cpResource.getResourceid();
    }


    @GetAction("{resourceid}/resource.json")
    @With(ILogin.class)
    @Description("通用-获取资源对象(已实现)")
    public CpResource getRes(
        @Description("资源id")
        @NotNull String resourceid) {
        return cpResourceMapper.getResourceByKey(resourceid);
    }

    @PutAction("update.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-修改资源，返回更新资源的主键(已实现)")
    public String updateRes(
        @Description("要更新的资源对象")
        @NotNull(message = "必须传递资源数据") @Valid CpResource cpResource
    ) {
        String sameCodeName = cpResourceMapper.comCheckResourceCode(cpResource.getResourcecode(), cpResource.getResourceid());
        UserException.throwIf(S.isNotBlank(sameCodeName), S.fmt("编码%s已经被菜单:%s使用!", cpResource.getResourcecode(), sameCodeName));
        cpResourceMapper.updateTemplateById(cpResource);
        return cpResource.getResourceid();
    }

    @DeleteAction("{resourceid}/del.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-删除资源，返回删除资源的条数(已实现)")
    public int delRes(
        @NotNull(message = "必须指定要删除的记录") String resourceid
    ) {
        return cpResourceMapper.comDeleteResourceById(resourceid);
    }


    @PutAction("save.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-保存资源排序和结构(已实现)")
    public int saveStructureRes(
        @NotNull(message = "没有传递数据!") List<CpResource> menus
    ) {
        _save(menus, null);
        return 0;
    }


    private void _save(List<CpResource> menus, CpResource menu){
        int index = 0;
        for(int i = 0 ; i < menus.size(); i ++){
            CpResource item = menus.get(i);
            item.setOrderno(i);
            item.setResourcepid(menu == null ? null : menu.getResourceid());
            cpResourceMapper.updateTemplateById(item);
            _save(item.getMenus(), item);
        }
    }
}
